#region Copyright Jonathan Quiros

//	
// All rights are reserved. Reproduction or transmission in whole or in 
// part, in any form or by any means, electronic, mechanical or otherwise, 
// is prohibited without the prior written consent of the copyright owner.
//
// Filename: TeamsRepository.cs
//

#endregion

using System;
using System.Linq;
using System.Collections.Generic;
using Ids.Web.Listing;
using Novagoal.Models;
using Novagoal.Models.Utils;
using Novagoal.Repositories.Extensions;

namespace Novagoal.Repositories.Entities
{
    public class TeamsRepository : BaseRepository, ITeamsRepository
    {
        #region CONSTANTS



        #endregion

        #region PROPERTIES

        

        #endregion

        #region PUBLIC METHODS

        public List<Team> GetTeamsByTournament(int tournamentId)
        {
            return EntitiesContext.tournaments_teams
                .Where(tt => tt.tournaments.id == tournamentId)
                .Select(tt => tt.teams)
                .Select(CreateTeam)
                .OrderBy(t => t.Name)
                .ToList();
        }

        public List<Team> GetTeams(Dictionary<TeamListFilter, string> filterList, TeamListSortField sortField, SortDirectionType sortDirection, int currentPage, int pageSize)
        {
            var qryTeams = FilterTeams(filterList);

            var teams = SortTeams(qryTeams, sortField, sortDirection)
                .TakePage(currentPage, pageSize)
                .AsEnumerable()
                .Select(CreateTeam)
                .ToList();

            return teams;
        }

        public List<Team> GetTeams()
        {
            return EntitiesContext.teams
                .Select(CreateTeam)
                .OrderBy(t => t.Name)
                .ToList();
        }

        public int GetTotalTeams(Dictionary<TeamListFilter, string> filterList)
        {
            return FilterTeams(filterList).Count();
        }

        public Team GetTeam(int teamId)
        {
            return EntitiesContext.teams
                .Where(t => t.id == teamId)
                .Select(CreateTeam)
                .FirstOrDefault();
        }

        public int AddTeam(Team team)
        {
            var entity = new teams
                             {
                                 name = team.Name,
                                 flag = team.FlagPath,
                                 created_at = UniversalDate,
                                 updated_at = UniversalDate,
                                 updated_by = team.UpdatedBy
                             };
            EntitiesContext.AddToteams(entity);
            EntitiesContext.SaveChanges();
            return entity.id;
        }

        public int EditTeam(Team team)
        {
            var entity = EntitiesContext.teams
                .Where(t => t.id == team.Id)
                .FirstOrDefault();

            entity.name = team.Name;
            entity.flag = team.FlagPath;
            entity.updated_at = UniversalDate;
            entity.updated_by = team.UpdatedBy;

            return entity.id;
        }

        public Dictionary<Team, bool> GetTeamsByPlayer(int playerId)
        {
            return EntitiesContext.players_teams
                .Where(pt => pt.players.id == playerId)
                .Select(pt => new {pt.teams, pt.enabled})
                .ToDictionary(d => CreateTeam(d.teams), d => d.enabled);
        }

        public void DeleteAllPlayerTeams(int playerId)
        {
            var teams = EntitiesContext.players_teams
                .Where(pt => pt.players.id == playerId)
                .ToList();

            foreach (var team in teams)
            {
                EntitiesContext.DeleteObject(team);
            }
            
            EntitiesContext.SaveChanges();
        }

        public void AddPlayerInTeam(Player player, int teamId, bool enabled)
        {
            var entity = new players_teams
                             {
                                 players = EntitiesContext.players.Where(p => p.id == player.Id).FirstOrDefault(),
                                 teams = EntitiesContext.teams.Where(t => t.id == teamId).FirstOrDefault(),
                                 enabled = enabled,
                                 created_at = UniversalDate,
                                 updated_at = UniversalDate,
                                 updated_by = player.UpdatedBy
                             };
            EntitiesContext.AddToplayers_teams(entity);
            EntitiesContext.SaveChanges();
        }

        #endregion

        #region PRIVATE METHODS

        private IQueryable<teams> FilterTeams(Dictionary<TeamListFilter, string> filters)
        {
            var teams = EntitiesContext.teams as IQueryable<teams>;

            if (filters != null)
            {
                if (filters.Keys.Contains(TeamListFilter.Id))
                {
                    int id;
                    if (int.TryParse(filters[TeamListFilter.Id], out id))
                    {
                        return teams.Where(item => item.id == id);
                    }
                }
                if (filters.Keys.Contains(TeamListFilter.Name))
                {
                    var strName = filters[TeamListFilter.Name];
                    teams = teams.Where(item => item.name.Contains(strName));
                }
            }

            return teams;
        }

        private IQueryable<teams> SortTeams(IQueryable<teams> query, TeamListSortField sortField, SortDirectionType sortDirection)
        {
            switch (sortField)
            {
                case TeamListSortField.Id:
                    return query.OrderBy(item => item.id, sortDirection);

                case TeamListSortField.Name:
                    return query.OrderBy(item => item.name, sortDirection);

                case TeamListSortField.CreatedAt:
                    return query.OrderBy(item => item.created_at, sortDirection);

                case TeamListSortField.UpdatedAt:
                    return query.OrderBy(item => item.updated_at, sortDirection);

            }
            return query.OrderByDescending(item => item.id);
        }

        #endregion
    }
}